package profile

import (
	"context"
	profilepb "coolcar/proto/profile_out/v1"
	"fmt"

	"go.mongodb.org/mongo-driver/mongo/options"

	"go.mongodb.org/mongo-driver/bson"

	"go.mongodb.org/mongo-driver/mongo"
)

type Mongo struct {
	col *mongo.Collection
	//newObjID func() primitive.ObjectID
	//nowFunc  func() time.Time
}

func NewMongo(db *mongo.Database) *Mongo {
	return &Mongo{
		col: db.Collection("profile"),
		//newObjID: primitive.NewObjectID,
		//nowFunc:  time.Now,
	}
}

type Record struct {
	AccountID   string              `bson:"accoundid"`
	Profile     *profilepb.Proflile `bson:"profile"`
	PhotoBlobID string              `bson:"photoblobid"`
}

func (m *Mongo) GetProfile(c context.Context, accountID string) (*Record, error) {
	res := m.col.FindOne(c, bson.M{
		"accountid": accountID,
	})
	if res.Err() != nil {
		return nil, res.Err()
	}

	pr := Record{}
	err := res.Decode(&pr)
	if err != nil {
		return nil, fmt.Errorf("can not decode profile: %v \n", err.Error())
	}

	return &pr, nil
}

func (m *Mongo) UpdateProfile(c context.Context, accountID string, prevStatus profilepb.IdentityStatus, p *profilepb.Proflile) error {
	_, err := m.col.UpdateOne(c, bson.M{
		"accountid": accountID,
		"$or": []bson.M{
			{
				"profile.identitystatus": prevStatus,
			},
			{
				"profile.identitystatus": bson.M{
					"$exists": false,
				},
			},
		},
	}, bson.M{
		"accountid": accountID,
		"profile":   p,
	}, options.Update().SetUpsert(true))

	return err
}

func (m *Mongo) UpdateProfilePhoto(c context.Context, accountID string, blobID string) error {
	_, err := m.col.UpdateOne(c, bson.M{
		"accountid": accountID,
	}, bson.M{
		"accountid":   accountID,
		"photoblobid": blobID,
	}, options.Update().SetUpsert(true))

	return err
}
